package com.wynne.ptldemo.statemachine;


import com.wynne.ptldemo.bo.TagSignalBo;
import com.wynne.ptldemo.consts.ResultBean;
import com.wynne.ptldemo.enums.TriggerType;
import com.wynne.ptldemo.pojo.PtlRouteStatus;
import com.wynne.ptldemo.service.IRouteService;
import com.wynne.ptldemo.util.SpringContextUtil;
import com.wynne.ptldemo.ws.StationWebSocket;
import org.springframework.util.ObjectUtils;
import org.squirrelframework.foundation.fsm.annotation.StateMachineParameters;
import org.squirrelframework.foundation.fsm.impl.AbstractUntypedStateMachine;

import java.util.List;
import java.util.Optional;

//FIXME check
// 1. 流程中断之后，如何续前运行 缓存什么东西？ eg: 流程中间需要外部触发 流程中断
// 2. 目前组件运行结果分了两个分支success和failure 当一个状态可以触发大于两个状态的时候，如何去区分事件 //fixed
// 3. 状态机的context需要详细定义，因为都是基于context的字段执行流程
/**
 * {@link TagSignalBo}
 **/
@StateMachineParameters(stateType = String.class, eventType = String.class, contextType = TagSignalBo.class)
public class RouteActionStateMachine extends AbstractUntypedStateMachine {

    private StationWebSocket webSocket;

    private IRouteService routeService;

    private static final String SUCCESS = "SUCCESS";
    private static final String FAILURE = "FAILURE";

    public RouteActionStateMachine() {
        webSocket = (StationWebSocket) SpringContextUtil.getBean("stationWebSocket");
        routeService = (IRouteService) SpringContextUtil.getBean("moduleDispatcher");
    }

    public void trigger(String from, String to, String event, TagSignalBo context) {
        webSocket.sendMessage("1", "--------从：" + from + " --- 到：" + to + " --- 触发:" + event + "--------");
        Optional<PtlRouteStatus> routeStatusOpt = getPtlRouteStatus(context.getRouteStatusList(), from, to, event);
        routeStatusOpt.ifPresent(d -> {
            context.setCurRouteStatus(routeStatusOpt.get());

            ResultBean resultBean = routeService.execRoute(context, routeStatusOpt.get().getActionAmgId());
            //we can get the route we wanted from result bean if we add a field to PtlRouteStatus
            if (routeStatusOpt.get().getTriggerType() == TriggerType.INNER_TRIGGER.getValue()) {
                if (resultBean.isSuccess()) {
                    fire(SUCCESS, context);
                } else {
                    fire(FAILURE, context);
                }
            } else {
                //外部触发
            }
        });
    }

    public void entry(String from, String to, String event, TagSignalBo context) {
        webSocket.sendMessage("1", "--------进入:" + to + "--------");
        if (ObjectUtils.isEmpty(context.getCurRouteStatus())) {
            return;
        }

        ResultBean resultBean = routeService.execRoute(context, context.getCurRouteStatus().getInAmgId());
    }

    public void exit(String from, String to, String event, TagSignalBo context) {
        webSocket.sendMessage("1", "--------离开:" + from + "--------");
        if (ObjectUtils.isEmpty(context.getCurRouteStatus())) {
            return;
        }
        ResultBean resultBean = routeService.execRoute(context, context.getCurRouteStatus().getOutAmgId());
    }

    private Optional<PtlRouteStatus> getPtlRouteStatus(List<PtlRouteStatus> context, String from, String to, String event) {
        Optional<PtlRouteStatus> routeStatusOptional = context.stream().
                filter(d -> d.getStatusCode().equals(from) && d.getNextStatus().equals(to) && d.getTriggerEvent().equals(event)).
                findFirst();

        return routeStatusOptional;
    }


}
